#ifndef PROPERTIES_HPP
#define	PROPERTIES_HPP
#define YYSTYPE Properties
#include <string>
#include "types.hpp"

using namespace std;

/*
 * Esta struct define os atributos de cada nó na árvore de derivação construída
 * pelo parser recursivo descendente. Seus métodos modificam a struct para prover
 * geração de código. Os atributos são:
 *
 *   * code - Código necessário para gerar a tradução do nó. Para constantes,
 *     aparece como vazio.
 *
 *   * value - Nome da variável que armazena o valor do nó, quando se trata de
 *     alguma expressão. Quando é uma constante, contém diretamente o valor da
 *     constante. Para nós que não possuam valor, como um loop, é vazia.
 *
 *   * type - Tipo da expressão armazenada neste nó. Fundamental na maior parte
 *     das operações aritméticas.
 *
 *   * constant - Descreve se o conteúdo armazenado corresponde a uma constante
 *     no programa fonte e no destino ou não.
 */
struct Properties {
    string code;
    string value;
    Type* type;
    bool constant;
    Properties();
    Properties(string code, string value, Type* type, bool constant = false);
    // Obtém o tipo de um identificador referenciado após sua declaração.
    void check();
    // Obtém o tipo de um identificador referenciado após sua declaração.
    // Atribui o identificador passado a esta instância.
    void check(Properties& var);
    // Gera a saída do programa.
    void program(Properties& defs, Properties& code);
    // Soma códigos de dois nós.
    void concat(Properties& code1, Properties& code2);
    // Gera código de atribuição.
    void assignment(Properties& id, Properties & exp);
    // Gera código para atribui a uma posição de um vetor.
    void arrayassign(Properties& arrai, Properties& index, Properties & exp);
    // Gera código para troca de variáveis.
    void swapping(Properties& var1, Properties & var2);
    // Gera código de operação aritmética ou lógica.
    void operation(Properties& opl, Properties& opr, Operator ops);
    // Gera código para indexação de vetor.
    void arrayitem(Properties& array, Properties & index);
    // Código para if com then, apenas.
    void ifthen(Properties& test, Properties & comand);
    // Código para if com then e else.
    void ifthenelse(Properties& test, Properties& com, Properties & alt);
    // Código para laços de iteração de intervalo.
    void iterate(Properties& index, Properties& a, Properties& b, Properties & comand);
    // Código para laço com verificação prévia.
    void ifloop(Properties& test, Properties & comand);
    // Código para laço com verificação posterior.
    void loopif(Properties& test, Properties & comand);
    // Código para impressão.
    void print(Properties & var);
    // Código para entrada.
    void scan(Properties & var);
    // Código para negação numérica ou lógica de um termo.
    void negatedterm(Properties& id, Operator negop);
    // Código para geração de uma instrução return dentro do corpo de uma função.
    void returner(Properties& exp);
};


#endif	/* PROPERTIES_HPP */

